#!/usr/bin/python
# vim: fdm=marker fmr={{{,}}} cms=#%s

import sys
import socket
import getopt
import re

def usage(selfname):
#{{{
    print "Usage: %s" % selfname
    print "    -h | --help"
    print "    -s 'host:port' | --server='host:port'"
    print "    [-c '...' | --command='...']"
#}}}

def call(sock, cmd):
#{{{
    p=cmd.find(" ");
    if p == -1:
        c=cmd
    else:
        c=cmd[:p]
    c=c.upper();
    if c == "EXIT" or c == "QUIT" or c == "BYE":
        return None;

    try:
        sock.sendall(cmd+"\r\n")
    except socket.gaierror, e:
        print "send to server fail"
        return None

    resp=''
    while 1:
        try:
            buf=sock.recv(1024)
        except socket.error, e:
            print "recv from server fail: %s" % e
            return None
        if not len(buf):
            break
        resp+=buf
        if resp[-5:] == "\r\n.\r\n":
            resp=resp[:len(resp)-5]
            break
    return resp
#}}}

def main(argc, argv):
#{{{
    if argc < 3:
        usage(argv[0])
        return 1

    try:
        opts,args=getopt.getopt(argv[1:], "hs:c:", ["help", "server=", "command="])
    except getopt.GetoptError:
        usage(argv[0])
        return 1
    if not opts:
        usage(argv[0])
        return 1
    server_addr,cmd=('','')
    for opt,arg in opts:
        #print "%s %s" % (opt,arg)
        if opt in ("-h", "--help"):
            usage(argv[0])
            return 0
        elif opt in ("-s", "--server"):
            server_addr=arg
        elif opt in ("-c", "--command"):
            cmd=arg

    res=re.search(":", server_addr)
    if not res:
        print "server_addr(%s) invalid" % (server_addr)
        return 1
    try:
        key,value=server_addr.split(':')
        host=key
        port=int(value)
    except ValueError:
        print "server_addr(%s) parse fail" % (server_addr)
        return 1
    #print "%s:%s" % (host,port)

    sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        sock.connect((host, port))
    except socket.gaierror, e:
        print "address-related error: %s" % e
        return 1
    except socket.error, e:
        print "connect to server fail: %s" % e
        return 1

    resp=None
    if cmd:
        resp=call(sock, cmd)
        if resp:
            print resp
    else:
        prompt=server_addr+'> '
        while 1:
            cmd=raw_input(prompt)
            re.sub('^ *', '', cmd)
            re.sub(' *$', '', cmd)
            if not cmd:
                 continue
            resp=call(sock, cmd)
            if not resp: break
            print resp

    sock.close()
#}}}

if __name__ == '__main__':
    main(len(sys.argv), sys.argv)
